package com.kgdev.cweb.mbean.store.order;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;
import org.primefaces.model.UploadedFile;

import com.kgdev.cweb.beans.prod.impl.OrderBean;
import com.kgdev.cweb.beans.prod.impl.OrderDraftBean;
import com.kgdev.cweb.beans.pub.impl.ChocolateColorBean;
import com.kgdev.cweb.beans.pub.impl.ChocolateColorBodyBean;
import com.kgdev.cweb.beans.pub.impl.ChocolateTypeBean;
import com.kgdev.cweb.beans.pub.impl.OrderQuantityBean;
import com.kgdev.cweb.beans.pub.impl.PlateArticleBean;
import com.kgdev.cweb.beans.pub.impl.PlatePackingBean;
import com.kgdev.cweb.entities.prod.managed.Order;
import com.kgdev.cweb.entities.prod.managed.OrderDraft;
import com.kgdev.cweb.entities.prod.owned.order.OrderAttributes;
import com.kgdev.cweb.entities.prod.owned.order.OrderPattern;
import com.kgdev.cweb.entities.pub.ChocolateColor;
import com.kgdev.cweb.entities.pub.ChocolateColorBody;
import com.kgdev.cweb.entities.pub.ChocolateType;
import com.kgdev.cweb.entities.pub.OrderQuantity;
import com.kgdev.cweb.entities.pub.OrderStatus;
import com.kgdev.cweb.entities.pub.PlateArticle;
import com.kgdev.cweb.entities.pub.PlatePacking;
import com.kgdev.cweb.entities.sys.Image;
import com.kgdev.cweb.mbean.global.session.LoginBean;

@ManagedBean
@SessionScoped
public class OrderAdd implements Serializable {

	private static final long serialVersionUID = 1L;
	@EJB
	OrderBean orderBean;
	@EJB
	OrderDraftBean orderDraftBean;
	@EJB
	PlateArticleBean plateArticleBean;
	@EJB
	OrderQuantityBean orderQuantityBean;
	@EJB
	ChocolateColorBean chocolateColorBean;
	@EJB
	ChocolateColorBodyBean chocolateColorBodyBean;
	@EJB
	PlatePackingBean platePackingBean;
	@EJB
	ChocolateTypeBean chocolateTypeBean;

	@ManagedProperty(value = "#{loginBean}")
	LoginBean loginBean;

	private OrderDraft orderDraft;

	// ---Lists used in forms
	private List<PlateArticle> plateArticles;
	private List<Integer> quantities;
	private List<ChocolateColorBody> chocolateColorBodies;
	private List<ChocolateColor> chocolateColors;
	private List<PlatePacking> platePackings;
	private List<ChocolateType> chocolateTypes;

	// ---/Lists used in forms

	public Boolean articleHasBody() {

		if (orderDraft.getPlateArticle() == null)
			return false;
		if (orderDraft.getPlateArticle().getHasBody() == null)
			return false;
		return orderDraft.getPlateArticle().getHasBody();
	}

	public String cancelSaveDraft() {
		saveDraft();
		initNewDraft();
		return "cancelOrderAdd";
	}

	public String deleteDraft() {
		orderDraftBean.remove(orderDraft.getOrderDraftId());
		initNewDraft();
		return "cancelOrderAdd";
	}

	public String dontSaveDraft() {
		initNewDraft();
		return "cancelOrderAdd";
	}

	public StreamedContent getBufferDownloadFile() {
		InputStream stream = new ByteArrayInputStream(orderDraft.getLogotype()
				.getContent());
		return new DefaultStreamedContent(stream, orderDraft.getLogotype()
				.getContentType(), orderDraft.getLogotype().getFileName());
	}

	public List<ChocolateColorBody> getChocolateColorBodies() {
		return chocolateColorBodies;
	}

	public List<ChocolateColor> getChocolateColors() {
		return chocolateColors;
	}

	public List<ChocolateType> getChocolateTypes() {
		return chocolateTypes;
	}

	public int getInscriptionCountDown() {
		if (orderDraft.getInscription() == null) {
			return 45;
		}
		return 45 - orderDraft.getInscription(). // TODO hardcoded 45
				toCharArray().length;
	}

	public OrderDraft getOrderDraft() {
		return orderDraft;
	}

	public List<PlateArticle> getPlateArticles() {
		return plateArticles;
	}

	public List<PlatePacking> getPlatePackings() {
		return platePackings;
	}

	public List<Integer> getQuantities() {
		return quantities;
	}

	public void handleLogotypeUpload(FileUploadEvent event) {
		UploadedFile file = event.getFile();
		System.err.println("File name: " + file.getFileName());

		// Setting order name to logo name WHY???????!!!!!!!!!!!
		try {
			orderDraft.setOrderName(new String(file.getFileName().getBytes(),
					"utf8"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace(); // TODO
		}

		byte[] content = file.getContents(); // TODO stub

		Image image = new Image();
		image.setContent(content);
		image.setFileName(file.getFileName());
		image.setContentType(file.getContentType());
		orderDraft.setLogotype(image);

		String message = "Upload sucessful";
		FacesMessage facesMessage = new FacesMessage(message,
				file.getFileName());
		FacesContext.getCurrentInstance().addMessage(null, facesMessage);

	}

	@PostConstruct
	public void init() {
		System.err.println("orderadd init");
		initLists();
		initNewDraft();
	}

	public Boolean inscriptionNotEmpty() {
		return (orderDraft.getInscription() != null)
				&& (orderDraft.getInscription() != "");
	}

	public boolean logotypeExists() {
		return orderDraft.getLogotype() != null;
	}

	public String makeOrderFromDraft(Integer orderDraftId) {
		initLists();
		orderDraft = orderDraftBean.find(orderDraftId);
		return "makeOrderFromDraft";
	}

	public void orderAdd() {
		orderBean.add(processOrderFromDraft());
		initNewDraft();
	}

	public String previewOrder() {
		// TODO hardcoded logotype validation
		if (!logotypeExists()) {
			FacesContext
					.getCurrentInstance()
					.addMessage(
							null,
							new FacesMessage(
									FacesMessage.SEVERITY_ERROR,
									"order:Logotype: Validation Error: Value is required.",
									"Please, upload you'r company's logotype"));

			return "";
		}

		return "toOrderAddPreview";
	}

	public void resetLogotype() {
		orderDraft.setLogotype(null);
	}

	public void saveDraft() {
		if (orderDraftBean.find(orderDraft.getOrderDraftId()) == null)
			orderDraftBean.add(orderDraft);
		else
			orderDraftBean.edit(orderDraft);
	}

	public void setChocolateColorBodies(
			List<ChocolateColorBody> chocolateColorBodies) {
		this.chocolateColorBodies = chocolateColorBodies;
	}

	public void setChocolateColors(List<ChocolateColor> chocolateColors) {
		this.chocolateColors = chocolateColors;
	}

	public void setChocolateTypes(List<ChocolateType> chocolateTypes) {
		this.chocolateTypes = chocolateTypes;
	}

	public void setLoginBean(LoginBean loginBean) {
		this.loginBean = loginBean;
	}

	public void setOrderDraft(OrderDraft orderDraft) {
		this.orderDraft = orderDraft;
	}

	public void setPlateArticles(List<PlateArticle> plateArticles) {
		this.plateArticles = plateArticles;
	}

	public void setPlatePackings(List<PlatePacking> platePackings) {
		this.platePackings = platePackings;
	}

	public void setQuantities(List<Integer> quantities) {
		this.quantities = quantities;
	}

	private void initLists() {
		plateArticles = plateArticleBean.findAll();
		chocolateColorBodies = chocolateColorBodyBean.findAll();
		chocolateColors = chocolateColorBean.findAll();
		platePackings = platePackingBean.findAll();
		chocolateTypes = chocolateTypeBean.findAll();

		List<OrderQuantity> quantityObjs = orderQuantityBean.findAll();
		quantities = new ArrayList<>();
		for (OrderQuantity orderQuantity : quantityObjs) {
			quantities.add(orderQuantity.getQuantity());
		}
	}

	private void initNewDraft() {
		setOrderDraft(new OrderDraft());
		orderDraft.setClient(loginBean.getAutenticatedClient());
		orderDraft.setOrderDraftDate(new Date(Calendar.getInstance().getTime()
				.getTime()));
	}

	private OrderAttributes processOrderAttributes(OrderDraft orderDraft) {
		OrderAttributes orderAttributes = new OrderAttributes();
		orderAttributes.setBodyColor(orderDraft.getBodyColor());
		orderAttributes.setLogoColor(orderDraft.getLogoColor());
		orderAttributes.setInscriptionColor(orderDraft.getInscriptionColor());
		orderAttributes.setPlateColor(orderDraft.getPlateColor());
		orderAttributes.setQuantity(orderDraft.getQuantity());
		//TODO
		return orderAttributes;

	}

	private Order processOrderFromDraft() {
		Order order = new Order();
		order.setClient(orderDraft.getClient());
		order.setOrderDate(new Date(Calendar.getInstance().getTimeInMillis()));
		order.setOrderName(orderDraft.getOrderName());
		order.setOrderAttributes(processOrderAttributes(orderDraft));
		order.setOrderPattern(processOrderPattern(orderDraft));
		order.setStatus(new OrderStatus("New"));
		return order;
	}

	private OrderPattern processOrderPattern(OrderDraft orderDraft) {
		OrderPattern orderPattern = new OrderPattern();
		orderPattern.setLogotype(orderDraft.getLogotype());
		orderPattern.setInscription(orderDraft.getInscription());
		orderPattern.setHasFrame(orderDraft.getHasFrame());
		return orderPattern;
	}

}
